package fun.ticsmyc.question;

import org.junit.Test;

import java.util.Arrays;

/**
 * @author Ticsmyc
 * @package fun.ticsmyc.question
 * @date 2020-02-13 18:28
 */
public class 矩阵的各种打印方式 {


    @Test
    public void testPrintAround(){
        转圈打印矩阵 a= new 转圈打印矩阵();
        //int[][] arr= new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        //int[][] arr= new int[][]{{1,2,3},{4,5,6},{7,8,9}};
        //int[][] arr= new int[][]{{1},{2},{3}};
        //int[][] arr= new int[][]{};
        int[][] arr= new int[][]{{1,2,3}};
        a.print(arr);
    }

    @Test
    public void testRoute(){
        矩阵旋转90度 a= new 矩阵旋转90度();
        int[][] arr= new int[][]{{1,2,3},{4,5,6},{7,8,9}};
        for(int i=0;i<3;++i){
            System.out.println(Arrays.toString(arr[i]));
        }
        a.divide(arr);
        for(int i=0;i<3;++i){
            System.out.println(Arrays.toString(arr[i]));
        }
    }

    @Test
    public void testZhi(){
        之字形打印矩阵 a = new 之字形打印矩阵();
//        int[][] arr= new int[][]{{1,2,3},{4,5,6},{7,8,9}};
       // int[][] arr= new int[][]{{1,2},{3,4},{5,6}};
//        int[][] arr= new int[][]{};
//        int[][] arr= new int [3][3];
        int[][] arr= new int[][]{{1,2,3}};
        a.divide(arr);

    }

    @Test
    public void testFind(){
        排好序的矩阵中找数 a = new 排好序的矩阵中找数();
        int[][] arr= new int[][]{{1,3,5,7},{10,15,29,30}};
        a.find(arr,0);

    }

}

class 排好序的矩阵中找数{
    public void find(int[][] arr,int x ){
        if(arr.length ==0 ){
            return ;
        }
        int row = arr.length;
        int column =arr[0].length;

        //从右上角arr[i][j]开始找
        int i =0;
        int j = column-1;

        while(i<row && i>=0 && j<column&&j>=0){
            if(arr[i][j] < x){
                i++;
            }else if(arr[i][j] >x){
                j--;
            }else{
                System.out.println("Yes");
                return;
            }
        }

        System.out.println("No");
    }

}


class 之字形打印矩阵{
    /**
     * 将矩阵分隔为若干个斜列，对每列调用print方法
     */
    public void divide(int[][] arr){
        if(arr.length ==0){
            return ;
        }
        //几行
        int row = arr.length;
        //几列
        int column  = arr[0].length;

        int[] leftDown=new int[]{0,0};
        int[] rightUp=new int[]{0,0};
        boolean up = true;
        print(arr,leftDown,rightUp,up);
        while(true){
            leftDown[1] = (leftDown[0] ==row-1)?leftDown[1]+1:leftDown[1];
            leftDown[0] = (leftDown[0] ==row-1)?leftDown[0]:leftDown[0]+1;
            rightUp[0] = (rightUp[1] == column-1)?rightUp[0]+1 : rightUp[0];
            rightUp[1] = (rightUp[1]==column-1) ? rightUp[1]:rightUp[1]+1;
            up=!up;
            print(arr,leftDown,rightUp,up);

            if(leftDown[0]==row-1 && leftDown[1]==column-1 &&leftDown[0]==rightUp[0] && leftDown[1]==rightUp[1]){
                break;
            }
        }
    }

    private void print(int[][] arr, int[] leftDown, int[] rightUp,boolean up){

        if(up){
            int i=leftDown[0];
            int j =leftDown[1];
            //从leftDown开始，到rightUP
            while(i >= rightUp[0] || j <= rightUp[1]){
                System.out.println(arr[i--][j++]);
            }
        }else{
            int i=rightUp[0];
            int j =rightUp[1];
            //从rightUp到leftDown
            while(i <= leftDown[0] || j >= leftDown[1]){
                System.out.println(arr[i++][j--]);
            }
        }
    }
}

class 转圈打印矩阵{


    public void printOneRound(int[][] arr, int lr,int lc,int rr,int rc){

        if(lr == rr ){
            //横向一维
            for(int i = lc; i<=rc ; ++i){
                System.out.println(arr[lr][i]);
            }
            return;
        }
        if(lc ==rc ){
            //纵向一维
            for(int i =lr; i<=rr;++i){
                System.out.println(arr[i][rc]);
            }
            return;
        }
        //先打印上面的框, lr不变，lc从lc->rc-1
        for(int i = lc; i<rc ; ++i){
            System.out.println(arr[lr][i]);
        }
        //再打印右边的框
        for(int i =lr; i<rr;++i){
            System.out.println(arr[i][rc]);
        }
        //下面的框
        for(int i =rc; i>lc ;--i){
            System.out.println(arr[rr][i]);
        }
        //左边的框
        for(int i =rr ; i>lr;--i){
            System.out.println(arr[i][lc]);
        }
    }

    public void print(int[][] arr){
        if(arr.length==0){
            return;
        }
        int row = arr.length;  //几行
        int column = arr[0].length;  //几列

        int lr =0;
        int lc =0;
        int rr=row-1;
        int rc = column-1;

        while(lr<= rr && lc <= rc){
            printOneRound(arr,lr++,lc++,rr--,rc--);
        }

    }
}

class 矩阵旋转90度{

    public void divide(int[][] arr){
        if(arr.length==0){
            return;
        }
        int row = arr.length;  //几行
        int column = arr[0].length;  //几列

        int lr =0;
        int lc =0;
        int rr=row-1;
        int rc = column-1;

        while(lr<= rr && lc <= rc){
            routeExchange(arr,lr++,lc++,rr--,rc--);
        }
    }
    public void routeExchange(int[][] arr, int lr,int lc, int rr , int rc){
        int[] leftUp=new int[]{lr,lc};
        int[] leftDown=new int[]{rr,lc};
        int[] rightUp=new int[]{lr,rc};
        int[] rightDown = new int[]{rr,rc};

        for(int i=lc ; i<rc;++i){
            int index = i-lc;

            int temp= arr[leftUp[0]][leftUp[1]+index];
            arr[leftUp[0]][leftUp[1]+index] = arr[leftDown[0]-index][leftDown[1]];
            arr[leftDown[0]-index][leftDown[1]] = arr[rightDown[0]][rightDown[1]-index];
            arr[rightDown[0]][rightDown[1]-index] = arr[rightUp[0]+index][rightUp[1]];
            arr[rightUp[0]+index][rightUp[1]]=temp;
        }
    }
}
